﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.IO;

namespace ModelUML
{
    [Serializable]
    public class Model1 : KontenerUML
    {
        override public List<String> Validate()
        {
            List<String> lista = new List<string>();
            foreach (ElementUML el in Elementy)
            {
                lista.AddRange(el.Validate());                
            }
            if (lista.Count == 0) lista.Add("Nie znaleziono błędów");
            return lista;
        }
        public static Model1 staticModel = null;
        public Model1(String nazwa)
        {
            Nazwa = nazwa;
            staticModel = this;
        }
        public void WczytajModel(Model1 model)
        {
            Elementy.Wyczysc();
            foreach (ElementUML el in model.Elementy)
            {
                this.Elementy.Dodaj(el);
            }
        }
        private String spacje(int x)
        {
            String n = "";
            for (int i = 0; i < x; i++) n += " ";
            return n;
        }
        public void GenerujKodPHP(Stream stream)
        {
            int wciecie = 0;
            const int rozmiar = 4;

            StreamWriter sw = new StreamWriter(stream);
            sw.WriteLine("<?php");
            List<AsocjacjaUML> asocjacje = new List<AsocjacjaUML>();
            foreach (ElementUML el in Elementy)
            {
                if (el.JestAsocjacja)
                {
                    asocjacje.Add((AsocjacjaUML)el);
                }
            }
            foreach (ElementUML el in Elementy)
            {
                if (el.JestKlasa)
                {
                    sw.Write(spacje(wciecie) + el.Visibility.ToString() + " class " + el.Nazwa);
                    bool flaga = false;
                    foreach (AsocjacjaUML aso in asocjacje)
                    {
                        if (aso.konce[0].OwnedEnd == el)
                        {
                            if (aso.konce[1].EndType == AsocjacjaUML.EndTypeEnum.generalizacja)
                            {
                                if (aso.konce[1].OwnedEnd.JestKlasa)
                                {
                                    sw.Write(" extends " + aso.konce[1].OwnedEnd.Nazwa);
                                    break;
                                }
                                
                            }
                        }
                        else if (aso.konce[1].OwnedEnd == el)
                        {
                            if (aso.konce[0].EndType == AsocjacjaUML.EndTypeEnum.generalizacja)
                            {
                                if (aso.konce[0].OwnedEnd.JestKlasa)
                                {
                                    sw.Write(" extends " + aso.konce[0].OwnedEnd.Nazwa);
                                    break;
                                }
                            }
                        }
                    }
                    sw.WriteLine();
                    sw.WriteLine(spacje(wciecie) + "{");
                    wciecie += rozmiar;
                    foreach (AtrybutUML atr in ((KlasaUML)el).atrybuty)
                    {
                        sw.WriteLine(spacje(wciecie) + atr.Visibility.ToString() + " $" + atr.Nazwa + ";");
                    }
                    foreach (OperacjaUML ope in ((KlasaUML)el).operacje)
                    {
                        sw.Write(spacje(wciecie) + ope.Visibility.ToString() + " " + ope.Typ.Nazwa + " " + ope.Nazwa + "(");
                        for (int i = 0; i < ope.atrybuty.Count; i++)
                        {
                            AtrybutUML atr = ope.GetAtrybut(i);
                            sw.Write("$" + atr.Nazwa);
                            if (i > ope.atrybuty.Count - 1) sw.Write(", ");
                        }
                        sw.WriteLine(") {}");
                    }
                    wciecie -= rozmiar;
                    sw.WriteLine(spacje(wciecie) + "}");
                }
            }            
            sw.WriteLine(">");

            sw.Close();
            stream.Close();
        }
        public void GenerujKodCSharp(Stream stream)
        {
            int wciecie = 0;
            const int rozmiar = 4;

            StreamWriter sw = new StreamWriter(stream);
            sw.WriteLine("namespace {0}", this.Nazwa);
            sw.WriteLine("{");
            wciecie += rozmiar;
            List<AsocjacjaUML> asocjacje = new List<AsocjacjaUML>();
            foreach (ElementUML el in Elementy)
            {
                if (el.JestAsocjacja)
                {
                    asocjacje.Add((AsocjacjaUML)el);
                }
            }
            foreach (ElementUML el in Elementy)
            {
                if (el.JestKlasa)
                {
                    sw.Write(spacje(wciecie) + el.Visibility.ToString() + " class " + el.Nazwa);
                    bool flaga = false;
                    foreach (AsocjacjaUML aso in asocjacje)
                    {
                        if (aso.konce[0].OwnedEnd == el)
                        {
                            if (aso.konce[1].EndType == AsocjacjaUML.EndTypeEnum.generalizacja)
                            {
                                sw.Write((flaga ? ", " : ": ") + aso.konce[1].OwnedEnd.Nazwa);
                                flaga = true;
                            }
                        }
                        else if (aso.konce[1].OwnedEnd == el)
                        {
                            if (aso.konce[0].EndType == AsocjacjaUML.EndTypeEnum.generalizacja)
                            {
                                sw.Write(flaga ? ", " : ": " + aso.konce[0].OwnedEnd.Nazwa);
                                flaga = true;
                            }
                        }
                    }
                    sw.WriteLine();
                    sw.WriteLine(spacje(wciecie) + "{");
                    wciecie += rozmiar;
                    foreach (AtrybutUML atr in ((KlasaUML)el).atrybuty)
                    {
                        sw.WriteLine(spacje(wciecie) + atr.Visibility.ToString() + " " + atr.Typ.Nazwa + " " + atr.Nazwa + ";");
                    }
                    foreach (OperacjaUML ope in ((KlasaUML)el).operacje)
                    {
                        sw.Write(spacje(wciecie) + ope.Visibility.ToString() + " " + ope.Typ.Nazwa + " " + ope.Nazwa + "(");
                        for (int i = 0; i < ope.atrybuty.Count; i++)
                        {
                            AtrybutUML atr = ope.GetAtrybut(i);
                            sw.Write(atr.Typ.Nazwa + " " + atr.Nazwa);
                            if (i > ope.atrybuty.Count - 1) sw.Write(", ");
                        }
                        sw.WriteLine(") {}");
                    }
                    wciecie -= rozmiar;
                    sw.WriteLine(spacje(wciecie) + "}");
                }
            }
            wciecie -= rozmiar;
            sw.WriteLine("}");

            sw.Close();
            stream.Close();
        }

        public void GenerujKodJava(DirectoryInfo dir)
        {
            int wciecie = 0;
            const int rozmiar = 4;

            List<AsocjacjaUML> asocjacje = new List<AsocjacjaUML>();
            foreach (ElementUML el in Elementy)
            {
                if (el.JestAsocjacja)
                {
                    asocjacje.Add((AsocjacjaUML)el);
                }
            }
            if (!dir.Exists) dir.Create();
            foreach (ElementUML el in Elementy)
            {
                if (el.JestKlasa)
                {
                    FileInfo fi = new FileInfo(dir.FullName + "//" + el.Nazwa + ".java");
                    FileStream fs = fi.Create();

                    StreamWriter sw = new StreamWriter(fs);
                    sw.WriteLine("namespace {0}", this.Nazwa);
                    sw.WriteLine("{");
                    wciecie += rozmiar;

                    sw.Write(spacje(wciecie) + el.Visibility.ToString() + " class " + el.Nazwa);
                    bool flaga = false;
                    foreach (AsocjacjaUML aso in asocjacje)
                    {
                        if (aso.konce[0].OwnedEnd == el)
                        {
                            if (aso.konce[1].EndType == AsocjacjaUML.EndTypeEnum.generalizacja)
                            {
                                if (aso.konce[1].OwnedEnd.JestInterfejsem)
                                {
                                    sw.Write(" implements " + aso.konce[1].OwnedEnd.Nazwa);
                                    break;
                                }
                                else if (aso.konce[1].OwnedEnd.JestKlasa)
                                {
                                    sw.Write(" extends " + aso.konce[1].OwnedEnd.Nazwa);
                                    break;
                                }
                            }
                        }
                        else if (aso.konce[1].OwnedEnd == el)
                        {
                            if (aso.konce[0].EndType == AsocjacjaUML.EndTypeEnum.generalizacja)
                            {
                                if (aso.konce[1].OwnedEnd.JestInterfejsem)
                                {
                                    sw.Write(" implements " + aso.konce[1].OwnedEnd.Nazwa);
                                    break;
                                }
                                else if (aso.konce[1].OwnedEnd.JestKlasa)
                                {
                                    sw.Write(" extends " + aso.konce[1].OwnedEnd.Nazwa);
                                    break;
                                }
                            }
                        }
                    }
                    sw.WriteLine();
                    sw.WriteLine(spacje(wciecie) + "{");
                    wciecie += rozmiar;
                    foreach (AtrybutUML atr in ((KlasaUML)el).atrybuty)
                    {
                        sw.WriteLine(spacje(wciecie) + atr.Visibility.ToString() + " " + atr.Typ.Nazwa + " " + atr.Nazwa + ";");
                    }
                    foreach (OperacjaUML ope in ((KlasaUML)el).operacje)
                    {
                        sw.Write(spacje(wciecie) + ope.Visibility.ToString() + " " + ope.Typ.Nazwa + " " + ope.Nazwa + "(");
                        for (int i = 0; i < ope.atrybuty.Count; i++)
                        {
                            AtrybutUML atr = ope.GetAtrybut(i);
                            sw.Write(atr.Typ.Nazwa + " " + atr.Nazwa);
                            if (i > ope.atrybuty.Count - 1) sw.Write(", ");
                        }
                        sw.WriteLine(") {}");
                    }
                    wciecie -= rozmiar;
                    sw.WriteLine(spacje(wciecie) + "}");
                    wciecie -= rozmiar;
                    sw.WriteLine("}");

                    sw.Flush();
                    sw.Close();
                    fs.Close();
                }
            }
        }
    }
}
